﻿using System;
using System.Globalization;
using System.Text.RegularExpressions;

namespace BloggerAutoPosterService.Engine.Utils
{
    /// <summary>
    /// Persian Date Converter
    /// </summary>
    public static class PersianUtils
    {
        #region Methods (6)

        // Public Methods (6) 

        public static string ApplyUnifiedYeKe(this string data)
        {
            return string.IsNullOrEmpty(data) ? string.Empty : data.Replace("ي", "ی").Replace("ك", "ک");
        }

        public static bool ContainsFarsi(this string txt)
        {
            return !string.IsNullOrEmpty(txt) &&
                    Regex.IsMatch(txt, @"[\u0600-\u06FF]");
        }

        public static string PersianDayWeekName(this DateTime dateTime)
        {
            var res = dateTime.DayOfWeek.ToString();

            switch (res)
            {
                case "Saturday":
                    res = "شنبه";
                    break;

                case "Sunday":
                    res = "يك شنبه";
                    break;

                case "Monday":
                    res = "دو شنبه";
                    break;

                case "Tuesday":
                    res = "سه شنبه";
                    break;

                case "Wednesday":
                    res = "چهار شنبه";
                    break;

                case "Thursday":
                    res = "پنج شنبه";
                    break;

                case "Friday":
                    res = "جمعه";
                    break;
            }

            return res;
        }

        public static string ShamsiMonthName(int shamsiMonthNumber)
        {
            string name = "";

            switch (shamsiMonthNumber)
            {
                case 1:
                    name = "فروردين";
                    break;
                case 2:
                    name = "ارديبهشت";
                    break;
                case 3:
                    name = "خرداد";
                    break;
                case 4:
                    name = "تير";
                    break;
                case 5:
                    name = "مرداد";
                    break;
                case 6:
                    name = "شهريور";
                    break;
                case 7:
                    name = "مهر";
                    break;
                case 8:
                    name = "آبان";
                    break;
                case 9:
                    name = "آذر";
                    break;
                case 10:
                    name = "دي";
                    break;
                case 11:
                    name = "بهمن";
                    break;
                case 12:
                    name = "اسفند";
                    break;
            }

            return
                name;
        }

        /// <summary>
        /// Converts Gregorian date to Shamsi/Persian date
        /// </summary>
        /// <param name="gregorianDate">Gregorian date</param>
        /// <param name="separator">Defines an optional separator between date's parts. Its default value is /</param>
        /// <param name="includeHourMinute">Should converter include hour and minutes in final result. Its default value is true</param>
        /// <param name="includePersianDayWeekName"></param>
        /// <returns>Persian/Shamsi DateTime string</returns>
        public static string ToPersianDateTime(
            this DateTime gregorianDate,
            string separator = "/",
            bool includeHourMinute = true,
            bool includePersianDayWeekName = false)
        {
            var gregorianYear = gregorianDate.Year;
            var gregorianMonth = gregorianDate.Month;
            var gregorianDay = gregorianDate.Day;
            var persianCalendar = new PersianCalendar();
            var persianYear = persianCalendar.GetYear(new DateTime(gregorianYear, gregorianMonth, gregorianDay, new GregorianCalendar()));
            var persianMonth = persianCalendar.GetMonth(new DateTime(gregorianYear, gregorianMonth, gregorianDay, new GregorianCalendar()));
            var persianDay = persianCalendar.GetDayOfMonth(new DateTime(gregorianYear, gregorianMonth, gregorianDay, new GregorianCalendar()));
            var result = includeHourMinute ?
                string.Format(CultureInfo.InvariantCulture, "{0}:{1}  {2}{3}{4}{3}{5}", gregorianDate.Hour, gregorianDate.Minute, persianYear, separator, persianMonth.ToString("00", CultureInfo.InvariantCulture), persianDay.ToString("00", CultureInfo.InvariantCulture))
                : string.Format(CultureInfo.InvariantCulture, "{0}{1}{2}{1}{3}", persianYear, separator, persianMonth.ToString("00", CultureInfo.InvariantCulture), persianDay.ToString("00", CultureInfo.InvariantCulture));

            if (includePersianDayWeekName)
                result = string.Format("{0} {1}", gregorianDate.PersianDayWeekName(), result);

            return result;
        }

        public static string ToPersianDateTimeString(this DateTime gregorianDate)
        {
            var gregorianYear = gregorianDate.Year;
            var gregorianMonth = gregorianDate.Month;
            var gregorianDay = gregorianDate.Day;
            var persianCalendar = new PersianCalendar();
            var persianYear = persianCalendar.GetYear(new DateTime(gregorianYear, gregorianMonth, gregorianDay, new GregorianCalendar()));
            var persianMonth = persianCalendar.GetMonth(new DateTime(gregorianYear, gregorianMonth, gregorianDay, new GregorianCalendar()));
            var persianDay = persianCalendar.GetDayOfMonth(new DateTime(gregorianYear, gregorianMonth, gregorianDay, new GregorianCalendar()));

            return string.Format("{0} {1} {2} {3}",
                gregorianDate.PersianDayWeekName(),
                persianDay,
                ShamsiMonthName(persianMonth),
                persianYear);
        }

        #endregion Methods
    }
}
